package com.xmlt.core.template;

import java.util.List;

import javax.xml.xpath.XPathExpressionException;

import ognl.OgnlException;

import org.w3c.dom.Element;

import com.xmlt.core.template.instance.AbstractInstance;
import com.xmlt.core.template.instance.MultiInstance;
import com.xmlt.core.template.instance.Value;
import com.xmlt.core.template.tags.AbstractSectionElementVisitor;
import com.xmlt.core.template.tags.ITemplateSectionElementVisitor;
import com.xmlt.core.template.tags.TemplateSectionElement;
import com.xmlt.core.template.tags.TextTag;

public class TemplateSection {
	private String name;
	private List<TemplateSectionElement> bodyElements;

	public TemplateSection(String n, Element el) throws TemplateException {
		name = n;
		bodyElements = Utils.parseBody(el);
	}

	public TemplateSection(Element sectionEl) throws TemplateException {
		name = sectionEl.getAttribute("name");
		Element bodyEl = null;
		try {
			bodyEl = (Element) Utils.evaluateXPath(sectionEl, "body").item(0);
		} catch (XPathExpressionException e) {
			throw new TemplateException(e);
		}
		bodyElements = Utils.parseBody(bodyEl);
	}

	public String toString() {
		String s = "";
		s += "section: " + name + "\n";
		for (TemplateSectionElement el : bodyElements)
			s += el + "\n";
		return s;
	}

	public String getName() {
		return name;
	}

	public List<TemplateSectionElement> getTags() {
		return bodyElements;
	}

	public String generate(AbstractInstance instance) throws OgnlException {
		TextGenerationVisitor visitor = new TextGenerationVisitor(instance);
		accept(visitor);
		return visitor.getString();
	}
	
	public void accept(ITemplateSectionElementVisitor visitor) {
		for (TemplateSectionElement tse: bodyElements) {
			tse.accept(visitor);
		}
	}
	
	private class TextGenerationVisitor extends AbstractSectionElementVisitor {
		private StringBuffer stringBuffer;
		protected TextGenerationVisitor(AbstractInstance inst) {
			super(inst);
			stringBuffer = new StringBuffer();
		}
		
		public String getString() {
			return stringBuffer.toString();
		}
		
		@Override
		public void handleTextTag(TextTag textTag) {
			stringBuffer.append(textTag.getText());
		}
		@Override
		public void handleValue(Value value) {
			stringBuffer.append(value.getValue());
		}
		@Override
		public void handleMultiInstanceStart(MultiInstance multiInstance) {
		}
		@Override
		public void handleMultiInstanceEnd(MultiInstance multiInstance) {
		}
		@Override
		public void handleMultiInstanceItemStart(AbstractInstance itemInstance,
				MultiInstance multiInstance, int index) {
		}
		@Override
		public void handleMultiInstanceItemEnd(AbstractInstance itemInstance,
				MultiInstance multiInstance, int index) {
		}

		@Override
		public void handleObject(Object o) {
			stringBuffer.append(o);
		}

		@Override
		public void handleException(Exception e) {
			throw new RuntimeException(e);
		}
		
	}
}
